<?php

class Claycode_Router
{
	public $o_appController; 
	private $s_method;
	private $arr_methodParams;
	private static $o_instance;
	private $arr_constants;
	private $arr_applications;
	private $arr_forms;
	private $s_appRequestVarName;
	public $s_currAppIdent;
	
	public $arr_currAppConf;
	
	public function __construct()
	{
		//include the applications declaration file
		$this->arr_applications = Claycode_configuration::getInstance()->getApplicationsArray();
		$this->s_appRequestVarName = Claycode_configuration::getInstance()->getApplicationRequestVarName();
		$this->arr_methodParams = array();
		
		$this->arr_constants = array(
			'def_method'=> 'start',
			'controllers_dir'=> 'controllers',
			'controller_suffix'=> '',
			'error_controller'=> 'Error404Controller',
			'navi_request_delim'=> '/'
		);
		//check if we are browsing safely
		if(SessionHandler::getInstance()->browsingSafe() == true){
			//check if it is an ajax request
			if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
				//ajax requested
				
				if($_SERVER['REQUEST_METHOD'] == 'GET'){
					$arr_request = $_GET;
				}else{
					$arr_request = $_POST;
				}
				$this->routeAjax($arr_request);
			}else{
				if(isset($_GET) && !empty($_GET)){
					$this->manageAppRequests($_GET);
				}else{
					$this->getDefaultApp();
				}
				
				if(isset($_POST) && !empty($_POST)) {
					$this->routeFormSubmit($_POST);
				}
			}
		}
	}
	
	private function manageAppRequestParams($arr_appRequestParams)
	{
		
		//print_r($arr_appRequestParams);
	}
	
	private function manageAppRequests($s_request)
	{
		if(!empty($s_request)){
			//get the necessary values
			//main app request
			
			if(isset($this->s_appRequestVarName)){
				//find the application configuration via the controller alias name
				
				$this->arr_currAppConf = Claycode_configuration::getInstance()->getAppConfArray($s_request[$this->s_appRequestVarName]);
				if(!empty($this->arr_currAppConf)){
					$this->o_appController = $this->arr_currAppConf['controller_class'];
				}
				
				//route the correct method call
				if(isset($this->arr_currAppConf['action']) && !empty($this->arr_currAppConf['action'])){
					$this->s_method = $this->arr_currAppConf['action'];
				}else{
					$this->s_method = $this->arr_constants['def_method'];
				}
			} else {
				$this->getDefaultApp();
			}
		}
		
	}
	private function getDefaultApp()
	{
		//include the default configuration file that is in the custom package
		$this->o_appController = Claycode_configuration::getInstance()->getDefaultController();
		
		$this->arr_currAppConf = Claycode_configuration::getInstance()->getCurrentAppConfByControllerName($this->o_appController);
		//redirect to the right controller
		$this->s_method = $this->arr_constants['def_method'];
		header('location:' . fw_util_buildUrl($this->arr_currAppConf['controller_class_alias'], '', true, false));
	}
	
	public static function getInstance()
	{
		if(!isset(self::$o_instance) ||  self::$o_instance == null) {
			self::$o_instance = new Claycode_Router();
		}
		return self::$o_instance;
	}
	
	public function route()
	{
		//check if we are browsing safely first
		if(SessionHandler::getInstance()->browsingSafe() == true){
			//identify the current application 
			$this->s_currAppIdent = $this->arr_currAppConf['app_ident'];
			//set it in the configuration class
			Claycode_configuration::getInstance()->setCurrentAppConf($this->arr_currAppConf);
			
			$file = C_FW_customPackage
				  . $this->arr_constants['controllers_dir'] 
				  . '/'  
				  . $this->o_appController 
				  . $this->arr_constants['controller_suffix'] 
				  . '.php';
			
			
			if(is_readable($file)) {
				include $file;
				
				$s_className = $this->o_appController . $this->arr_constants['controller_suffix'];
			} else {
				/*
				//launch the default app on a no controller found occurence
				$this->getDefaultApp();
				include C_FW_customPackage
					  . $this->arr_constants['controllers_dir'] 
					  . '/'  
					  . $this->o_appController 
					  . $this->arr_constants['controller_suffix'] 
					  . '.php';
					
				$s_className = $this->o_appController . $this->arr_constants['controller_suffix'];
				*/
				
				//if you want the default to be the error controller uncomment this
				include C_FW_customPackage .$this->arr_constants['controllers_dir'] . '/' .$this->arr_constants['error_controller']  .'.php';
				$s_className = $this->arr_constants['error_controller'];
				
			}
			
			$o_controller = new $s_className();
			if (is_callable(array($o_controller, $this->s_method))) {
				$s_action = $this->s_method;
				if(!empty($this->arr_methodParams)){
					//has parameters for the method to call
					$o_controller->$s_action($this->arr_methodParams);
				}else{
					
					$o_controller->$s_action();
				}
			} else {
				$s_action = $this->arr_constants['def_method'];
				$o_controller->$s_action();
			}
			
		}
	}
	
	private function routeAjax($arr_request)
	{
		if(SessionHandler::getInstance()->browsingSafe() == true){
			//die(fw_util_outputJson(array( 'serviceName'=> $arr_request['serviceName'])));
			if(isset($arr_request['serviceName'])) {
				switch ($arr_request['serviceName'])
				{
					case 'GetHeaderTitle':
						//die(fw_util_outputJson(array( 'args'=> $arr_request['args'])));
						fw_util_outputJson(array( 'args'=> $arr_request['args']));
						break;
				}
			}
		}
	}
	
	public function routeFormSubmit($arr_postVals)
	{
		//check if browsing safe first
		if(SessionHandler::getInstance()->browsingSafe() == true){
			$s_submitHandlerFieldName = Claycode_configuration::getInstance()->getFormPostSubmitHandler();
			$s_formIdentField = Claycode_configuration::getInstance()->getFormIdentField();
			if(isset($_POST[$s_submitHandlerFieldName]) && isset($_POST[$s_formIdentField])){
				$s_submitId = $_POST[$s_submitHandlerFieldName];
				if(isset($_SESSION[$s_submitId])){
					unset($_SESSION[$s_submitId]);
					//the identity of the form
					$s_formIdent = $_POST[$s_formIdentField];
					//get the configuration array of the form
					$arr_formConfig = Claycode_configuration::getInstance()->getFormConfig($s_formIdent , true);
					$this->setFormHandler($arr_formConfig);
				}
			}
		}
	}
	
	private function setFormHandler($arr_formConfig)
	{
		if(!empty($arr_formConfig)){
			if(isset($arr_formConfig['form_handler_class']) && isset($arr_formConfig['form_handler_class_method'])){
				$this->o_appController = $arr_formConfig['form_handler_class'];
				$this->s_method = $arr_formConfig['form_handler_class_method'];
			}else{
				$this->o_appController = $this->arr_constants['error_controller'];
			}
		}
	}
	
	
}